import pandas as pd
import os
from datetime import  date
import calendar
import re
import numpy as np
from progress.bar import Bar
'''
用来计算肖淋方的每月上播统计清单
1.从上播统计中获取对应店铺对应日期的上播人数
2.根据上播人数计算日报销金额
3.根据日报销金额计算报销金额
'''
# 配置年月（您可以根据需要修改这里）
config_year = 2025
config_month = 10
#是否开启别名功能，可能存在修改名称的店铺，需要开启别名功能
use_alias=True
#配置上播人数统计表
config_people_file = r'E:\files\10月上播人数1.xlsx'
# 配置平均上播人数范围和日报销金额的对应关系，左开右闭
avg_people_range={
    (0,199):15,
    (199,299):20,
    (299,399):25,
    (399,499):40,
    (499,599):50,
    (599):70
}


'''获取该月的所有日期'''  
def get_month_dates_alt(year, month):
    # 获取该月天数
    days_in_month = calendar.monthrange(year, month)[1]
    
    # 生成日期列表
    dates = []
    for day in range(1, days_in_month + 1):
        dates.append(date(year, month, day))
    
    return dates

'''创建店铺日期表'''  
def create_shop_date_table(year, month):
    # 获取该月所有日期
    dates = get_month_dates_alt(year, month)
    return dates

'''
定义提取日期数字的函数
'''
def extract_date_from_string(text):
    # 匹配形如 X.Y 的模式，其中 X 和 Y 是数字
    pattern = r'\d+\.\d+'
    match = re.search(pattern, text)
    if match:
        return match.group()
    return None

'''
获取源表的对应日期店铺的上播人数
'''  
def get_shop_people_online(df, shop_name, date):
    date_str = format_date(date)
    # 查找对应店铺的行对应日期的上播人数
    col_name = df.columns
    for col in col_name:
        if extract_date_from_string(col) == date_str:
             # 找到所有匹配的行
            matched_rows = df[df[col] == shop_name]
            
            if not matched_rows.empty:
                # 获取第一个匹配行的索引
                first_match_index = matched_rows.index[0]
                
                # 找到当前列的位置
                current_col_index = col_name.tolist().index(col)
                
                # 检查下一列是否存在
                if current_col_index + 1 < len(col_name):
                    # 获取下一列的名称
                    next_col_name = col_name[current_col_index + 1]
                    # 返回同一行的下一列的值
                    return df.loc[first_match_index, next_col_name]
                else:
                    print(f"警告：'{col}'列没有下一列，已到达DataFrame末尾")
                    return 0
            else:
                return 0
    return 0  # 如果没有找到匹配日期的列

'''日期转化为特定格式 月日'''  
def format_date_y_d(date):
   return date.month.__str__()+'月'+date.day.__str__()+'日'

'''日期转化为特定格式,只包含数字'''  
def format_date(date):
   return date.month.__str__()+'.'+date.day.__str__()

'''
计算出日报销金额
'''
def calculate_daily_sales(avg_people):
    return avg_people * 100

def get_reimbursement_by_people_count(people_count):
    """根据上播人数获取对应的报销标准"""
    for key, value in avg_people_range.items():
        # 检查键是否为元组（表示范围）
        if isinstance(key, tuple):
            # 不包含左边，包含右边
            if key[0] < people_count <= key[1]:
                return value
        # 检查键是否为单个数字（表示大于等于该值）
        elif isinstance(key, int):
            if people_count >= key:
                return value
    # 如果没有找到匹配的区间，返回默认值或抛出异常
    return 0  # 或者 raise ValueError(f"上播人数 {people_count} 不在任何定义的区间内")

if __name__ == '__main__':
    # 创建一个进度条对象
    bar = Bar('处理进度', max=100, suffix='%(percent)d%%',fill='◉',empty_fill='◯',bar_prefix='[',bar_suffix=']')
    #读取Excel文件
    current_dir = os.path.dirname(os.path.abspath(__file__))
    file_path = os.path.join(current_dir, 'shop.xlsx')
    
    try:
        # 读取店铺名称表
        tar = pd.read_excel(file_path)
        print(f"成功读取店铺表，共{len(tar)}家店铺")
        # 根据年月创建当月的每一天
        dates = create_shop_date_table(config_year, config_month)
        print(f"创建了{len(dates)}天的日期数据")
        # 创建新列（如果不存在）
        for date in dates:
            date_col = format_date_y_d(date)
            if date_col not in tar.columns:
                tar[date_col] = 0  # 初始化为0
        
        # 读取上播人数数据
        # 尝试使用相对路径，如果失败则提示用户
        try:
            # 首先尝试当前目录下的文件
            df = pd.read_excel(config_people_file)
            print(f"成功读取上播人数数据")
        except FileNotFoundError:
            # 如果失败，让用户输入正确的路径
            print(f"警告：未找到默认路径'{config_people_file}'，请输入正确的路径")
            people_file = input("请输入上播人数数据文件的路径（包含文件名）：")
            df = pd.read_excel(people_file)
            print(f"成功读取上播人数数据")
         # 计算总任务数（日期数 + 统计计算 + 文件保存）
        total_tasks = len(dates) + 3  # 日期处理 + 统计计算 + 文件保存 + 完成

        # 计算每个日期处理的进度增量
        progress_per_date = 80 / len(dates)  # 80%用于日期处理
        bar.message="处理日期上播人数"
        # 遍历所有日期和店铺，写入上播人数
        for index,date in enumerate(dates):
            for shop in tar["店铺名称"]:
                # 获取对应日期店铺的上播人数
                num = get_shop_people_online(df, shop, date)
                if num == 0 and use_alias:
                   #获取店铺别名进行查找
                   alias=tar.loc[tar["店铺名称"] == shop, "店铺别名"].values[0]
                   num = get_shop_people_online(df, alias, date)
                # 将上播人数写入店铺日期表对应的位置
                tar.loc[tar["店铺名称"] == shop, format_date_y_d(date)] = num
             # 更新进度条（每个日期处理完成后）
            current_progress = min(80, (index + 1) * progress_per_date)
            bar.next(int(current_progress))
        #统计每一行的平均每天上播人数、日报销金额、报销金额
        tar["平均每天上播人数"]=np.floor(tar[tar.columns[3 if use_alias else 2:]].mean(axis=1)).astype(int)
        # 日报销金额=平均每天上播人数*100
        tar["日报销金额"]=tar["平均每天上播人数"].apply(get_reimbursement_by_people_count)
        # 报销金额=日报销金额*当月的天数
        _,days_in_month = calendar.monthrange(config_year, config_month)
        tar["报销金额"]=tar["日报销金额"].apply(lambda x: x*(days_in_month))
         # 更新进度条到90%（统计计算完成）
        bar.message="处理统计数据"
        bar.next(90)
        # 生成excel文件
        output_file = os.path.join(current_dir, 'target',f'报销-{config_year}年-{config_month}月.xlsx')
        tar.to_excel(output_file, index=False)
        # 将进度条设置为100%
        bar.message="处理完成"
        bar.next(100)
        bar.finish()
        print(f"\n数据已成功写入：{output_file}")
        # 自动打开文件
        os.startfile(output_file)
    
        
    except Exception as e:
        print(f"处理过程中发生错误：{str(e)}")